package org.liang.code.rabbitMQ.工作队列模式;

import com.google.gson.Gson;
import com.rabbitmq.client.Channel;
import com.rabbitmq.client.Connection;
import org.liang.code.rabbitMQ.entity.SMS;
import org.liang.code.rabbitMQ.utils.RabbitConstant;
import org.liang.code.rabbitMQ.utils.RabbitUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.IOException;
import java.util.concurrent.TimeoutException;

/**
 * 发送消息
 */
public class OrderSystem {

    private static final Logger log = LoggerFactory.getLogger(OrderSystem.class);

    public static void main(String[] args) throws IOException, TimeoutException {

        try (
                // Connection 代表了应用程序与RabbitMQ服务器之间的物理TCP连接。
                // 当你使用 RabbitUtils.getConnection() 方法时，实际上是在建立一个到RabbitMQ服务器的网络连接。
                // 这个连接是一个相对较重的资源，因为它涉及到网络套接字的创建、TCP握手等操作。
                // 在一个应用程序中，通常只需要创建一个 Connection 实例，并且在整个应用程序的生命周期内复用它。
                Connection connection = RabbitUtils.getConnection();
                // Channel 是建立在 Connection 之上的轻量级抽象。
                // 它可以看作是一个虚拟连接，允许应用程序在同一个 Connection 上进行多个独立的操作。
                // 每个 Channel 都有自己独立的ID和状态，并且可以独立地进行消息的发送和接收。
                // 由于创建和销毁 Channel 的开销相对较小，因此在需要进行大量并发操作时，可以创建多个 Channel 来提高效率。
                Channel channel = connection.createChannel()
        ) {
            // 声明消息队列（参数说明：队列名称，持久化，排他性，自动删除，其他参数）
            // durable=true 表示队列持久化（服务重启后队列不会消失）
            // exclusive=false 表示非排他队列（允许多消费者连接）
            // autoDelete=false 表示不会自动删除（没有消费者也不会删除队列）
            channel.queueDeclare(RabbitConstant.QUEUE_SMS, true, false, false, null);

            // 循环发送 100 到 200 条 SMS 消息
            for (int i = 100; i <= 200; i++) {
                // 创建一个 SMS 对象
                SMS sms = new SMS("乘客" + i, "13900000" + i, "您的车票已预订成功");
                // 将 SMS 对象转换为 JSON 字符串
                String jsonSMS = new Gson().toJson(sms);
                // 发送 JSON 格式的 SMS 消息到 RabbitMQ 队列
                channel.basicPublish("", RabbitConstant.QUEUE_SMS, null, jsonSMS.getBytes());
            }
            log.info("订单信息已投递至Broker");
        }
    }
}
